In [1]:
import metakernel
metakernel.register_ipython_magics()
metakernel.__version__


Out[1]:
'0.13.3'

Limited lambda in Python

Python's lambda can only contain expressions (not statements). However, you don't need to use the word "return".


In [20]:
(lambda i: i + 1)


Out[20]:
<function __main__.<lambda>>

In [21]:
(lambda i: i + 1)(7)


Out[21]:
8

In [22]:
%%scheme

(lambda (i) (+ i 1))


Out[22]:
#<procedure>

In [23]:
%%scheme

((lambda (i) (+ i 1)) 7)


Out[23]:
8

Macros


In [16]:
%%scheme

(define for-repeat
  (lambda (n f)
    (if (< n 1)
        (void)
        (begin
          (f)
          (for-repeat (- n 1) f)))))

(define for-iterate1
  (lambda (values f)
    (if (null? values)
        (void)
        (begin
          (f (car values))
          (for-iterate1 (cdr values) f)))))

(define for-iterate2
  (lambda (i values f)
    (if (null? values)
        (void)
        (begin
          (f (car values) i)
          (for-iterate2 (+ i 1) (cdr values) f)))))


Out[16]:
<void>

In [18]:
%%scheme

(define-syntax for
  [(for ?exp times do . ?bodies)
   (for-repeat ?exp (lambda () . ?bodies))]
  [(for ?var in ?exp do . ?bodies)
   (for-iterate1 ?exp (lambda (?var) . ?bodies))]
  [(for ?var at (?i) in ?exp do . ?bodies)
   (for-iterate2 0 ?exp (lambda (?var ?i) . ?bodies))]
  [(for ?var at (?i ?j . ?rest) in ?exp do . ?bodies)
   (for ?var at (?i) in ?exp do
     (for ?var at (?j . ?rest) in ?var do . ?bodies))])


Out[18]:
<void>

Scope

Python's scopes are a bit enigmatic.

Closure


In [4]:
functions = []

for i in range(5):
    functions.append(lambda: i)

for f in functions:
    print(f())


4
4
4
4
4

In [19]:
%%scheme

(define functions '())

(for i in (range 5) do
    (set! functions (cons (lambda () i) functions)))

(for f in functions do
    (print (f)))


4
3
2
1
0
Out[19]:
<void>

In [ ]: